package com.zbkj.crmeb.store.service.impl;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.crmeb.core.utils.TableNameUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.utils.PriceUtil;
import com.utils.ProductConvertUtil;
import com.utils.ProductUtil;
import com.zbkj.crmeb.chant.model.CategoryMatch;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.service.ICategoryMatchService;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.enums.AreaTypeEnum;
import com.zbkj.crmeb.store.model.StoreProductMer;
import com.zbkj.crmeb.store.model.Supplier;
import com.zbkj.crmeb.store.service.StoreProductMerService;
import com.zbkj.crmeb.store.service.SupplierService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.PageParamRequest;
import com.crmeb.core.exception.CrmebException;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.front.request.UserCollectAllRequest;
import com.zbkj.crmeb.front.request.UserCollectRequest;
import com.zbkj.crmeb.store.dao.StoreProductRelationDao;
import com.zbkj.crmeb.store.model.StoreProduct;
import com.zbkj.crmeb.store.model.StoreProductRelation;
import com.zbkj.crmeb.store.request.StoreProductRelationSearchRequest;
import com.zbkj.crmeb.store.request.StoreProductSearchRequest;
import com.zbkj.crmeb.store.service.StoreProductRelationService;
import com.zbkj.crmeb.store.service.StoreProductService;
import com.zbkj.crmeb.store.vo.StoreProductRelationCountVo;
import com.zbkj.crmeb.user.service.UserService;

/**
* @author Mr.Zhang
* @description StoreProductRelationServiceImpl 接口实现
* @date 2020-05-27
*/
@Service
public class StoreProductRelationServiceImpl extends ServiceImpl<StoreProductRelationDao, StoreProductRelation>
        implements StoreProductRelationService {

    @Resource
    private StoreProductRelationDao dao;

    @Autowired
    private UserService userService;

    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private ProductUtil productUtil;
    @Autowired
    private ICategoryMatchService categoryMatchService;
    @Autowired
    private ProductConvertUtil productConvertUtil;
    @Autowired
    private PriceUtil priceUtil;
    @Autowired
    private StoreProductMerService storeProductMerService;
    @Autowired
    private IChannelMerchantService channelMerchantService;
    @Autowired
    private SupplierService supplierService;

    /**
     * 列表
     * @param request 请求参数
     * @param pageParamRequest 分页类参数
     * @author Mr.Zhang
     * @since 2020-05-06
     * @return List<StoreProductRelation>
     */
    @Override
    public List<StoreProduct> getList(String searchWord, StoreProductRelationSearchRequest request, PageParamRequest pageParamRequest,Integer merId) {

        List<Integer> productIds = null;
        if(StringUtil.isNotEmpty(searchWord)) {
            List<StoreProduct> productList = storeProductService.lambdaQuery().like(StoreProduct::getStoreName, searchWord).list();
            productIds = productList.stream().map(StoreProduct::getId).collect(Collectors.toList());
        }

        //带 StoreProductRelation 类的多条件查询
        LambdaQueryWrapper<StoreProductRelation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        StoreProductRelation storeProductRelation = new StoreProductRelation();
        BeanUtils.copyProperties(request, storeProductRelation);
        lambdaQueryWrapper.setEntity(storeProductRelation);
        lambdaQueryWrapper.in(productIds != null && productIds.size() > 0, StoreProductRelation::getProductId, productIds);
        lambdaQueryWrapper.orderByDesc(StoreProductRelation::getCreateTime);
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<StoreProductRelation> storeProductRelationList = dao.selectList(lambdaQueryWrapper);
        if(storeProductRelationList == null || storeProductRelationList.size() < 1){
            return new ArrayList<>();
        }
        List<Integer> productIdList = storeProductRelationList.stream().map(StoreProductRelation::getProductId).distinct().collect(Collectors.toList());
        if(productIdList.size() < 1){
            return new ArrayList<>();
        }
        List<StoreProduct> storeProductList = storeProductService.list(Wrappers.<StoreProduct>lambdaQuery().in(StoreProduct::getId, productIdList));
        if(CollectionUtils.isEmpty(storeProductList)){
            return new ArrayList<>();
        }
        productConvertUtil.convertProductImage(storeProductList);
        // 加价计算规则
        priceUtil.calcProductPrice(storeProductList, merId, AreaTypeEnum.CN.getType());
        List<Integer> enableCategoryMatchIds = categoryMatchService.getCategoryMatchIds(merId);
        Map<Integer, StoreProduct> productMap = storeProductList.stream().collect(Collectors.toMap(StoreProduct::getId, Function.identity()));
        // 商户自定义商品数据
        List<StoreProductMer> storeProductMers = storeProductMerService.list(Wrappers.<StoreProductMer>lambdaQuery()
                .in(StoreProductMer :: getProductId, storeProductList)
        );
        Map<Integer, StoreProductMer> storeProductMerMap = storeProductMers.stream().collect(Collectors.toMap(StoreProductMer::getProductId, Function.identity(), (key1, key2) -> key2));
        ChannelMerchant channelMerchant = channelMerchantService.getById(merId);
        Supplier supplier = supplierService.getSupplierBarcode(merId);
        List<Integer> brandIdsList = JSON.parseArray(channelMerchant.getBrandIds(), Integer.class);
        List<Integer> suppliersIdList = JSON.parseArray(channelMerchant.getSuppliersIds(), Integer.class);
        List<Integer> tempIdList = JSON.parseArray(channelMerchant.getTempId(), Integer.class);
        if (null != suppliersIdList && suppliersIdList.size() > 0) {
            if (null != supplier) {
                //商户如果是供应商的话 查询商户自建的商品 默认传入商户配置的供应商id
                suppliersIdList.add(supplier.getId());
            }
        }
        //失效判断
        for (Integer id : productIdList) {
            StoreProduct p = productMap.get(id);
            if(p != null){
                StoreProductMer spm = storeProductMerMap.get(p.getId());
                // 商户自定义下架状态
                boolean isMerShow = null == spm || !"1".equals(spm.getIsNotShow());
                //分类未启用时设置商品状态为失效
                boolean enableCategoryBool = !enableCategoryMatchIds.contains(p.getCateId());
                boolean enableBrand = CollectionUtils.isNotEmpty(brandIdsList) && !brandIdsList.contains(p.getBrandId());
                boolean enableSupplier = CollectionUtils.isNotEmpty(suppliersIdList) && !suppliersIdList.contains(p.getSuppliersId());
                boolean enableTemp = CollectionUtils.isNotEmpty(tempIdList) && !tempIdList.contains(p.getTempId());
                if(p.getStock() < 1 || !p.getIsShow() || !isMerShow || enableCategoryBool || enableBrand || enableSupplier || enableTemp || p.getIsDel()){
                    p.setIsFailure(true);
                }
            }
        }
        storeProductList.sort(((o1, o2) -> {
            int io1 = productIdList.indexOf(o1.getId());
            int io2 = productIdList.indexOf(o2.getId());
            return io1 - io2;
        }));
//        StoreProductSearchRequest storeProductSearchRequest = new StoreProductSearchRequest();
//        storeProductSearchRequest.setType(isNormal ? 1 : 2); //上架的商品
//        return storeProductService.getList(storeProductSearchRequest, pageParamRequest, productIdList,merId);
        return storeProductList;
    }

    @Override
    public List<StoreProduct> getFailureList(StoreProductRelationSearchRequest request, PageParamRequest pageParamRequest,Integer merId) {
        //带 StoreProductRelation 类的多条件查询
        LambdaQueryWrapper<StoreProductRelation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        StoreProductRelation storeProductRelation = new StoreProductRelation();
        BeanUtils.copyProperties(request, storeProductRelation);
        lambdaQueryWrapper.setEntity(storeProductRelation);
        lambdaQueryWrapper.orderByDesc(StoreProductRelation::getCreateTime);
        List<StoreProductRelation> storeProductRelationList = dao.selectList(lambdaQueryWrapper);
        if(storeProductRelationList == null || storeProductRelationList.size() < 1){
            return new ArrayList<>();
        }
        List<Integer> productIdList = storeProductRelationList.stream().map(StoreProductRelation::getProductId).distinct().collect(Collectors.toList());
        if(productIdList.size() < 1){
            return new ArrayList<>();
        }
        //查询失效商品
        ChannelMerchant channelMerchant = channelMerchantService.getById(merId);
        Supplier supplier = supplierService.getSupplierBarcode(merId);
        List<Integer> brandIdsList = JSON.parseArray(channelMerchant.getBrandIds(), Integer.class);
        List<Integer> suppliersIdList = JSON.parseArray(channelMerchant.getSuppliersIds(), Integer.class);
        List<Integer> tempIdList = JSON.parseArray(channelMerchant.getTempId(), Integer.class);
        tempIdList.add(0);
        if (null != suppliersIdList && suppliersIdList.size() > 0) {
            if (null != supplier) {
                //商户如果是供应商的话 查询商户自建的商品 默认传入商户配置的供应商id
                suppliersIdList.add(supplier.getId());
            }
        }
        List<Integer> enableCategoryMatchIds = categoryMatchService.getCategoryMatchIds(merId);
        enableCategoryMatchIds.add(0);
        LambdaQueryWrapper<StoreProduct> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(StoreProduct::getId,productIdList);
        queryWrapper.and(e->e.eq(StoreProduct::getIsDel,1)
                .or().notIn(CollectionUtils.isNotEmpty(brandIdsList),StoreProduct::getBrandId,brandIdsList)
                .or().notIn(CollectionUtils.isNotEmpty(suppliersIdList),StoreProduct::getSuppliersId,suppliersIdList)
                .or().notIn(StoreProduct::getCateId,enableCategoryMatchIds)
                .or().notIn(StoreProduct::getTempId,tempIdList)
                .or().le(StoreProduct::getStock,0)
                .or().eq(StoreProduct::getIsShow,false)
                .or().inSql(StoreProduct::getId, "SELECT product_id FROM " + TableNameUtil.getProductMerName(merId) + " WHERE is_not_show = 1")
        );
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<StoreProduct> storeProductList = storeProductService.list(queryWrapper);
        if(CollectionUtils.isEmpty(storeProductList)){
            return new ArrayList<>();
        }
        productConvertUtil.convertProductImage(storeProductList);
        // 加价计算规则
        priceUtil.calcProductPrice(storeProductList, merId, AreaTypeEnum.CN.getType());
        storeProductList.forEach(e->e.setIsFailure(true));
        return storeProductList;
    }

    /**
     * 根据类型和产品id获取总数
     * @param productIdList List<Integer> 产品id
     * @param type String 类型
     * @author Mr.Zhang
     * @since 2020-05-06
     * @return List<StoreProductRelationCountVo>
     */
    public List<StoreProductRelationCountVo> getCountInProductId(List<Integer> productIdList, String type) {
        HashMap<String, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("productId", productIdList);
        objectObjectHashMap.put("type", type);
        return dao.getCountInProductId(objectObjectHashMap);
    }

    /**
     * 根据产品id获取点赞总数
     * @param productIdList List<Integer> 产品id
     * @author Mr.Zhang
     * @since 2020-05-06
     * @return HashMap<Integer, Integer>
     */
    public HashMap<Integer, Integer> getLikeCountListInProductId(List<Integer> productIdList) {
        List<StoreProductRelationCountVo> list = getCountInProductId(productIdList, "like");
        return getCountListInProductId(list);
    }

    /**
     * 根据产品id获取收藏总数
     * @param productIdList List<Integer> 产品id
     * @author Mr.Zhang
     * @since 2020-05-06
     * @return HashMap<Integer, Integer>
     */
    public HashMap<Integer, Integer> getCollectCountListInProductId(List<Integer> productIdList) {
        List<StoreProductRelationCountVo> list = getCountInProductId(productIdList, "collect");
        return getCountListInProductId(list);
    }

    /**
     * 添加收藏产品
     * @param request UserCollectAllRequest 新增参数
     * @author Mr.Zhang
     * @since 2020-05-06
     * @return boolean
     */
    @Override
    public boolean all(UserCollectAllRequest request) {
        Integer[] arr = request.getProductId();
        if(arr.length < 1){
            throw new CrmebException("请选择产品");
        }

        List<Integer> list = CrmebUtil.arrayUnique(arr);

        Integer uid = userService.getUserIdException();
        deleteAll(request, uid, "collect");  //先删除所有已存在的

        ArrayList<StoreProductRelation> storeProductRelationList = new ArrayList<>();
        for (Integer productId: list) {
            StoreProductRelation storeProductRelation = new StoreProductRelation();
            storeProductRelation.setUid(uid);
            storeProductRelation.setType("collect");
            storeProductRelation.setProductId(productId);
            storeProductRelation.setCategory(request.getCategory());
            storeProductRelationList.add(storeProductRelation);
        }
        return saveBatch(storeProductRelationList);
    }


    /**
     * 取消收藏产品
     * @author Mr.Zhang
     * @since 2020-05-06
     */
    @Override
    public boolean delete(UserCollectRequest request) {
        LambdaQueryWrapper<StoreProductRelation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreProductRelation::getProductId, request.getProductId()).
                eq(StoreProductRelation::getUid, request.getUid()).
                eq(StoreProductRelation::getType, request.getType()).
                eq(StoreProductRelation::getCategory, request.getCategory());
        dao.delete(lambdaQueryWrapper);
        return true;
    }

    /**
     * 取消收藏产品
     * @param request UserCollectAllRequest 参数
     * @author Mr.Zhang
     * @since 2020-05-06
     */
    private void deleteAll(UserCollectAllRequest request, Integer uid, String type) {
        LambdaQueryWrapper<StoreProductRelation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(StoreProductRelation::getProductId, Arrays.asList(request.getProductId()))
                .eq(StoreProductRelation::getCategory, request.getCategory())
                .eq(StoreProductRelation::getUid, uid)
                .eq(StoreProductRelation::getType, type);
        dao.delete(lambdaQueryWrapper);
    }

    /**
     * product_id => count 数据组装
     * @param list List<StoreProductRelationCountVo> 数据集合
     * @author Mr.Zhang
     * @since 2020-05-06
     * @return HashMap<Integer, Integer>
     */
    private HashMap<Integer, Integer> getCountListInProductId(List<StoreProductRelationCountVo> list){
        HashMap<Integer, Integer> map = new HashMap<>();
        for (StoreProductRelationCountVo storeProductRelationCountVo : list){
            map.put(storeProductRelationCountVo.getProductId(), storeProductRelationCountVo.getCount());
        }
        return map;
    }

    /**
     * 根据产品id和类型获取对应列表
     * @param productId 产品id
     * @param type 类型
     * @return 对应结果
     */
    @Override
    public List<StoreProductRelation> getList(Integer productId, String type) {
        LambdaQueryWrapper<StoreProductRelation> lqr = new LambdaQueryWrapper<>();
        lqr.eq(StoreProductRelation::getProductId, productId);
        lqr.eq(StoreProductRelation::getType, type);
        return dao.selectList(lqr);
    }

    /**
     * 获取用户当前是否喜欢该商品
     * @param userId 用户id
     * @param productId 商品id
     * @return 是否喜欢标识
     */
    @Override
    public List<StoreProductRelation> getLikeOrCollectByUser(Integer userId, Integer productId,boolean isLike) {
        String typeValue = isLike?"like":"collect";
        LambdaQueryWrapper<StoreProductRelation> lqr = new LambdaQueryWrapper<>();
        lqr.eq(StoreProductRelation::getProductId, productId);
        lqr.eq(StoreProductRelation::getUid, userId);
        lqr.eq(StoreProductRelation::getType,typeValue);
        return dao.selectList(lqr);
    }

    @Override
    public boolean batchDelete(UserCollectRequest request) {
        return this.remove(Wrappers.<StoreProductRelation>lambdaQuery()
                .in(StoreProductRelation::getProductId, request.getProductIdList())
                .eq(StoreProductRelation::getCategory, request.getCategory())
                .eq(StoreProductRelation::getUid, request.getUid())
                .eq(StoreProductRelation::getType, request.getType())
        );
    }
    /**
     * 获取用户当前是否喜欢该商品
     * @param userId 用户id
     * @param productId 商品id
     * @return 是否喜欢标识
     */
    @Override
    public List<StoreProductRelation> getLikeOrCollectByUser(Integer userId, List<Integer> productIds,boolean isLike) {
        String typeValue = isLike?"like":"collect";
        LambdaQueryWrapper<StoreProductRelation> lqr = new LambdaQueryWrapper<>();
        lqr.in(StoreProductRelation::getProductId, productIds);
        lqr.eq(StoreProductRelation::getUid, userId);
        lqr.eq(StoreProductRelation::getType,typeValue);
        return dao.selectList(lqr);
    }

}

